﻿using Autofac;
using CSRedis;
using SH.Common;
using SH.Common.CommonClass;
using SH.Common.CommonReturn;

using SH.Common.Helper;
using SH.Multitenant.Application.IServices.IEmp;
using SH.Multitenant.Application.IServices.IUser;
using SH.Multitenant.Domain.RBAC;
using SH.Multitenant.Infrastructure.IRepository;
using SH.Multitenant.Infrastructure.Repository;
using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace SH.Multitenant.Application.Services
{
    public class EmpServices : BaseServices<Employee>, IEmpServices
    {
        private readonly IEmpRepository _empRepository;
        private readonly IStoreRepository _storeRepository;
        private readonly IEmpRoleRepository _empRoleRepository;
        private readonly CSRedisClient _redis = AppService.AutofacContainer.Resolve<CSRedisClient>();
        private readonly JwtTokenHelper _jwtHelper;

        #region private 

        #endregion

        public EmpServices(IEmpRepository repository, IStoreRepository storeRepository, JwtTokenHelper jwtHelper, IEmpRoleRepository empRoleRepository) : base(repository)
        {
            _empRepository = repository;
            _storeRepository = storeRepository;
            _jwtHelper = jwtHelper;
            _empRoleRepository = empRoleRepository;
        }
        //员工登录
        public async Task<ApiResult<LoginResponseDTO>> EmpLogin(LoginRequestDTO request)
        {
            ApiResult<LoginResponseDTO> apiResult = new ApiResult<LoginResponseDTO>();
            LoginResponseDTO response = new LoginResponseDTO();
            var emp = await _empRepository.GetEmployeeModel(request.StoreId, request.UName, request.UPwd);
            if (emp == null)
            {
                apiResult.Error(ApiResult<LoginResponseDTO>.ErrorType.Request, "用户名不存在");
            }
            else if (emp.EmpPwd != request.UPwd)
            {
                apiResult.Error(ApiResult<LoginResponseDTO>.ErrorType.Request, "账号密码不匹配");
            }
            else
            {
                var token = _jwtHelper.CreateJwtToken(emp, emp.TenantId);
                //登录成功
                response.UId = emp.EmpId;
                response.UName = emp.EmpName;
                response.TenantId = emp.TenantId;
                response.Token = token;

                apiResult.Success(response);
            }
            return apiResult;
        }
        //多条件获取员工列表
        public ApiPaging<List<EmployeeDTO>> ConditionQueryGetEmployees(int storeId, int flag, string? search, int pageSize, int pageIndex)
        {
            ApiPaging<List<EmployeeDTO>> apiPaging = new ApiPaging<List<EmployeeDTO>>();
            string tenantId = _redis.Get<string>("tenantId");
            //默认有管理员 且管理员不显示
            var employees = _empRepository.All.Where(x => x.EmpName != "admin" && x.TenantId == tenantId);
            var list = employees
                .LeftJoin<Store>((a, b) => a.StoreId == b.StoreId, "shmultitenantdb.store").Where(a => storeId == 0 || a.StoreId == storeId).Select((a, b) => new EmployeeDTO
                {
                    EmpId = a.EmpId,
                    Tel = a.Tel,
                    Email = a.Email,
                    Gender = a.Gender,
                    EmpStatus = a.EmpStatus,
                    StoreId = a.StoreId,
                    StoreName = b.StoreName,
                    RealName = a.RealName,
                    EntryTime = a.EntryTime,
                });
            Expression<Func<EmployeeDTO, bool>> predicate = x => true;
            if (!string.IsNullOrEmpty(search))
            {
                if (flag == 0)
                {
                    predicate = a => a.RealName!.Contains(search);
                }
                else
                {
                    predicate = a => a.Tel!.Contains(search);
                }
            }
            int totalCount = 0;
            int pageCount = 0;
            list = list.Where(predicate).OrderBy("EntryTime desc");
            totalCount = list.Count();
            pageCount = (int)Math.Ceiling(totalCount * 1.0 / pageSize);
            var empList = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

            apiPaging.TotalCount = totalCount;
            apiPaging.PageCount = pageCount;
            apiPaging.Data = empList;
            return apiPaging;
        }
        //员工添加
        public async Task<ApiResult<int>> EmployeeAddAsync(EmployeeAddDTO dto)
        {
            ApiResult<int> apiResult = new ApiResult<int>();
            using var tran = _empRepository.MultitenantUseTran();
            try
            {
                string newId = DateTime.Now.Ticks.ToString();


                //员工添加
                var result = await _empRepository.InsertAsync(new Employee
                {
                    EmpId = newId,
                    EmpName = dto.EmpName,
                    EmpPwd = dto.EmpPwd,//要经过MD5处理
                    Tel = dto.Tel,
                    Email = dto.Email,
                    Gender = dto.Gender,
                    EntryTime = dto.EntryTime,
                    EmpStatus = dto.EmpStatus,
                    StoreId = dto.StoreId,
                    RealName = dto.RealName,
                });
                if (result == 0)
                {
                    tran.RollbackTran();
                    apiResult.Error(ApiResult<int>.ErrorType.Service, "添加失败");
                    return apiResult;
                }
                //员工-角色表添加
                result = await _empRoleRepository.InsertAsync(new Emp_Role
                {
                    EmpId = newId,
                    RoleId = dto.RoleId,
                });
                if (result == 0)
                {
                    tran.RollbackTran();
                    apiResult.Error(ApiResult<int>.ErrorType.Service, "添加失败");
                    return apiResult;
                }
                tran.CommitTran();
                #region 同步Redis
                var employeeList = await _empRepository.GetListAsync();
                string tenantId = _redis.Get<string>("tenantId");
                _redis.HSet("employeeList", tenantId, employeeList);
                #endregion
                apiResult.Success();
                return apiResult;
            }
            catch (Exception)
            {
                tran.RollbackTran();
                throw;
            }


        }
        //员工信息修改
        public async Task<ApiResult<int>> UpdEmpInfoAsync(Employee employee)
        {
            ApiResult<int> apiResult = new ApiResult<int>();
            var emp = await _empRepository.GetModelByConditionAsync(x => x.EmpId == employee.EmpId);
            if (emp == null)
            {
                apiResult.Error(ApiResult<int>.ErrorType.Service, "未找到匹配的员工信息");
                return apiResult;
            }
            emp.EmpName = employee.EmpName;
            emp.Tel = employee.Tel;
            emp.Email = employee.Email;
            emp.Gender = employee.Gender;
            emp.EmpStatus = employee.EmpStatus;
            emp.StoreId = employee.StoreId;
            emp.RealName = employee.RealName;
            var result = _empRepository.Upd(emp);
            if (result > 0)
            {
                apiResult.Success();
            }
            else
            {
                apiResult.Error(ApiResult<int>.ErrorType.Service, "修改失败");
            }
            return apiResult;
        }
        //根据员工获取其角色编号
        public async Task<int> GetEmpRoleIdAsync(string empId)
        {
            var empRole = await _empRoleRepository.All.FirstAsync(x => x.EmpId == empId);
            return empRole.RoleId;
        }

        #region 唯一验证
        //判断用户名是否唯一
        public async Task<bool> EmpNameUnique(string empName)
        {

            var employee = await _empRepository.GetModelByConditionAsync(x => x.EmpName!.Equals(empName));
            return employee == null;
        }
        //判断手机号是否唯一
        public async Task<bool> TelUnique(string tel)
        {

            var employee = await _empRepository.GetModelByConditionAsync(x => x.Tel!.Equals(tel));
            return employee == null;
        }
        #endregion


    }
}
